#include "field.hpp"

using namespace std;

/* --------------------------------------------------------------- */
Field::Field(int r, int c, Sudoku * sudoku) {
	int i;
	this->sudoku = sudoku;
	row = r;
	column = c;
//	for(i = 1; i < 10; i++)
//		values.insert(i);
	value = 0;
	noOfValues = 9;
	memset(valuest, 0, sizeof(int) * 10);
}
/* --------------------------------------------------------------- */
void Field::createNeigSet() {
	int i, j, rs, cs;
	//h-lines
    for(j = 0; j < 9; j++) {
		if(j != this->column)
			neigs.insert(sudoku->getField(this->row, j));
    }

    //v-lines
    for(j = 0; j < 9; j++) {
		if(j != this->row)
			neigs.insert(sudoku->getField(j, this->column));
    }

	//squares
	rs = (row / 3) * 3;
	cs = (column / 3) * 3;
	for(i = rs; i < rs + 3; i++) {
		for(j = cs; j < cs + 3; j++) {
			if(i != this->row && j != this->column)
				neigs.insert(sudoku->getField(i, j));
		}
	}
	
}
/* --------------------------------------------------------------- */
int Field::getRow() {
	return row;
}
/* --------------------------------------------------------------- */
int Field::getColumn() {
	return column;
}
/* --------------------------------------------------------------- */
bool Field::setValue(int v) {
	//cout << "setValue("<<v<<") row="<<row<<", col="<<column<<"\n";
	//cout << "before set values= ";
//	printValues();
	std::set<Field*>::iterator it;
	if((checkValue(v)) || v == 0) {
		//cout << "setValue 0.5\n";
		if(value != v || v == 0) {
			//cout << "setValue 1\n";
			for(it = neigs.begin(); it != neigs.end(); it++) {
				//cout << "setValue 2\n";
				if(value != 0) {
					//cout << "setValue 3\n";
					(*it)->addValueToSet(value);
				}
				(*it)->removeValueFromSet(v);
			}
			///cout << "setValue 4\n";
			value = v;
			
			//printValues();
			/*
			for(it = neigs.begin(); it != neigs.end(); it++) {
				(*it)->printValues();
			}
			*/
			
			return true;
		}
	}
	//cout << "setValue 5\n";
	return false;

}
/* --------------------------------------------------------------- */
void Field::removeValueFromSet(int v) {
	//cout << "removeValue before size=" << values.size() << endl;
	//cout << "removeValueFromSet("<<v<<") row="<<row<<" col="<<column<<" \n";
	//values.erase(v);
	valuest[v]++;
	noOfValues--;
	//cout << "removeValue after size=" << values.size() << endl;
}
/* --------------------------------------------------------------- */
void Field::addValueToSet(int v) {
	//cout << "addValueToSet("<<v<<") row="<<row<<" col="<<column<<" \n";
	//values.insert(v);
	if(valuest[v] > 0)
		valuest[v]--;
	else {
		valuest[v] = 0; 
		noOfValues++;
	}
}
/* --------------------------------------------------------------- */
bool Field::checkValue(int v) {
	//cout << "checkValue: v=" << v << " " << endl;
	/*
	if(values.find(v) == values.end()) {
		cout << "checkValue: return false" << endl;
		return false;
	}
	*/
	//cout << "checkValue DUPA0" << endl;
	if(valuest[v] == 0 && value == 0)
		return true;
	//cout << "checkValue: return true" << endl;
	return false;
}
/* --------------------------------------------------------------- */
int Field::getValue() {
	return value;
}
/* --------------------------------------------------------------- */
void Field::printValues() {
	//std::set<int>::iterator it;
	cout << "Values of ("<<row<<","<<column<<"): ";
	/*
	for(it = values.begin(); it != values.end(); it++) {
		cout << *it << " ";
	}
	*/
	for(int i = 1; i < 10; i++)
		if(valuest[i] == 0)
			cout << i << " ";
	cout << endl;
}
/* --------------------------------------------------------------- */
void Field::showNeigh() {

	std::set<Field*>::iterator it;

	cout << "Neigbours of (" << row << "," << column << "):\n";
	cout << "neigs.size()=" << neigs.size() << endl;

	for(it = neigs.begin(); it != neigs.end(); it++) {
		cout << "\t(" << (*it)->getRow() << "," << (*it)->getColumn() << ")\n";
	}
}
/* --------------------------------------------------------------- */
int Field::getNoOfValues() {
	return noOfValues;
}

/* --------------------------------------------------------------- */
